home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gdevpdfg.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  28.8 KB  |  1,000 lines

  1. /* Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gdevpdfg.c,v 1.10 2000/09/19 19:00:17 lpd Exp $ */
  20. /* Graphics state management for pdfwrite driver */
  21. #include "math_.h"
  22. #include "string_.h"
  23. #include "gx.h"
  24. #include "gserrors.h"
  25. #include "gsfunc0.h"
  26. #include "gsstate.h"
  27. #include "gxbitmap.h"        /* for gxhttile.h in gzht.h */
  28. #include "gxdht.h"
  29. #include "gxfmap.h"
  30. #include "gxht.h"
  31. #include "gxistate.h"
  32. #include "gzht.h"
  33. #include "gdevpdfx.h"
  34. #include "gdevpdfg.h"
  35. #include "gdevpdfo.h"
  36. #include "szlibx.h"
  37.  
  38. /* ---------------- Miscellaneous ---------------- */
  39.  
  40. /* Reset the graphics state parameters to initial values. */
  41. void
  42. pdf_reset_graphics(gx_device_pdf * pdev)
  43. {
  44.     color_set_pure(&pdev->fill_color, 0);    /* black */
  45.     color_set_pure(&pdev->stroke_color, 0);    /* ditto */
  46.     pdev->state.flatness = -1;
  47.     {
  48.     static const gx_line_params lp_initial = {
  49.         gx_line_params_initial
  50.     };
  51.  
  52.     pdev->state.line_params = lp_initial;
  53.     }
  54.     pdev->fill_overprint = false;
  55.     pdev->stroke_overprint = false;
  56.     pdf_reset_text(pdev);
  57. }
  58.  
  59. /* Set the fill or stroke color. */
  60. private int
  61. pdf_reset_color(gx_device_pdf * pdev, const gx_drawing_color *pdc,
  62.         gx_drawing_color * pdcolor,
  63.         const psdf_set_color_commands_t *ppscc)
  64. {
  65.     int code;
  66.  
  67.     /*
  68.      * In principle, we can set colors in either stream or text
  69.      * context.  However, since we currently enclose all text
  70.      * strings inside a gsave/grestore, this causes us to lose
  71.      * track of the color when we leave text context.  Therefore,
  72.      * we require stream context for setting colors.
  73.      */
  74. #if 0
  75.     switch (pdev->context) {
  76.     case PDF_IN_STREAM:
  77.     case PDF_IN_TEXT:
  78.     break;
  79.     case PDF_IN_NONE:
  80.     code = pdf_open_page(pdev, PDF_IN_STREAM);
  81.     goto open;
  82.     case PDF_IN_STRING:
  83.     code = pdf_open_page(pdev, PDF_IN_TEXT);
  84.     open:if (code < 0)
  85.         return code;
  86.     }
  87. #else
  88.     code = pdf_open_page(pdev, PDF_IN_STREAM);
  89.     if (code < 0)
  90.     return code;
  91. #endif
  92.     code = pdf_put_drawing_color(pdev, pdc, ppscc);
  93.     if (code >= 0)
  94.     *pdcolor = *pdc;
  95.     return code;
  96. }
  97. int
  98. pdf_set_drawing_color(gx_device_pdf * pdev, const gx_drawing_color *pdc,
  99.               gx_drawing_color * pdcolor,
  100.               const psdf_set_color_commands_t *ppscc)
  101. {
  102.     if (gx_device_color_equal(pdcolor, pdc))
  103.     return 0;
  104.     return pdf_reset_color(pdev, pdc, pdcolor, ppscc);
  105. }
  106. int
  107. pdf_set_pure_color(gx_device_pdf * pdev, gx_color_index color,
  108.            gx_drawing_color * pdcolor,
  109.            const psdf_set_color_commands_t *ppscc)
  110. {
  111.     gx_drawing_color dcolor;
  112.  
  113.     if (gx_dc_is_pure(pdcolor) && gx_dc_pure_color(pdcolor) == color)
  114.     return 0;
  115.     color_set_pure(&dcolor, color);
  116.     return pdf_reset_color(pdev, &dcolor, pdcolor, ppscc);
  117. }
  118.  
  119. /* Get the (string) name of a separation, */
  120. /* returning a newly allocated string with a / prefixed. */
  121. /****** BOGUS for all but standard separations ******/
  122. int
  123. pdf_separation_name(gx_device_pdf *pdev, cos_value_t *pvalue,
  124.             gs_separation_name sname)
  125. {
  126.     static const char *const snames[] = {
  127.     gs_ht_separation_name_strings
  128.     };
  129.     static char buf[sizeof(ulong) * 8 / 3 + 2];    /****** BOGUS ******/
  130.     const char *str;
  131.     uint len;
  132.     byte *chars;
  133.  
  134.     if ((ulong)sname < countof(snames)) {
  135.     str = snames[(int)sname];
  136.     } else {            /****** TOTALLY BOGUS ******/
  137.     sprintf(buf, "S%ld", (ulong)sname);
  138.     str = buf;
  139.     }
  140.     len = strlen(str);
  141.     chars = gs_alloc_string(pdev->pdf_memory, len + 1, "pdf_separation_name");
  142.     if (chars == 0)
  143.     return_error(gs_error_VMerror);
  144.     chars[0] = '/';
  145.     memcpy(chars + 1, str, len);
  146.     cos_string_value(pvalue, chars, len + 1);
  147.     return 0;
  148. }
  149.  
  150. /* ------ Support ------ */
  151.  
  152. /* Print a Boolean using a format. */
  153. private void
  154. pprintb1(stream *s, const char *format, bool b)
  155. {
  156.     pprints1(s, format, (b ? "true" : "false"));
  157. }
  158.  
  159. /* ---------------- Graphics state updating ---------------- */
  160.  
  161. /* ------ Functions ------ */
  162.  
  163. /* Define the maximum size of a Function reference. */
  164. #define MAX_FN_NAME_CHARS 9    /* /Default, /Identity */
  165. #define MAX_FN_CHARS max(MAX_REF_CHARS + 4, MAX_FN_NAME_CHARS)
  166.  
  167. /*
  168.  * Create and write a Function for a gx_transfer_map.  We use this for
  169.  * transfer, BG, and UCR functions.  If check_identity is true, check for
  170.  * an identity map.
  171.  */
  172. private data_source_proc_access(transfer_map_access); /* check prototype */
  173. private int
  174. transfer_map_access(const gs_data_source_t *psrc, ulong start, uint length,
  175.             byte *buf, const byte **ptr)
  176. {
  177.     const gx_transfer_map *map = (const gx_transfer_map *)psrc->data.str.data;
  178.     uint i;
  179.  
  180.     if (ptr)
  181.     *ptr = buf;
  182.     for (i = 0; i < length; ++i)
  183.     buf[i] = frac2byte(map->values[(uint)start + i]);
  184.     return 0;
  185. }
  186. private int
  187. transfer_map_access_signed(const gs_data_source_t *psrc,
  188.                ulong start, uint length,
  189.                byte *buf, const byte **ptr)
  190. {
  191.     const gx_transfer_map *map = (const gx_transfer_map *)psrc->data.str.data;
  192.     uint i;
  193.  
  194.     *ptr = buf;
  195.     for (i = 0; i < length; ++i)
  196.     buf[i] = (byte)
  197.         ((frac2float(map->values[(uint)start + i]) + 1) * 127.5 + 0.5);
  198.     return 0;
  199. }
  200. private int
  201. pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
  202.                int range0, bool check_identity,
  203.                const char *key, char *ids)
  204. {
  205.     gs_memory_t *mem = pdev->pdf_memory;
  206.     gs_function_Sd_params_t params;
  207.     static const float domain01[2] = { 0, 1 };
  208.     static const int size = transfer_map_size;
  209.     float range01[2];
  210.     gs_function_t *pfn;
  211.     long id;
  212.     int code;
  213.  
  214.     if (map == 0) {
  215.     *ids = 0;        /* no map */
  216.     return 0;
  217.     }
  218.     if (check_identity) {
  219.     /* Check for an identity map. */
  220.     int i;
  221.  
  222.     if (map->proc == gs_identity_transfer)
  223.         i = transfer_map_size;
  224.     else
  225.         for (i = 0; i < transfer_map_size; ++i)
  226.         if (map->values[i] != bits2frac(i, log2_transfer_map_size))
  227.             break;
  228.     if (i == transfer_map_size) {
  229.         strcpy(ids, key);
  230.         strcat(ids, "/Identity");
  231.         return 1;
  232.     }
  233.     }
  234.     params.m = 1;
  235.     params.Domain = domain01;
  236.     params.n = 1;
  237.     range01[0] = range0, range01[1] = 1;
  238.     params.Range = range01;
  239.     params.Order = 1;
  240.     params.DataSource.access =
  241.     (range0 < 0 ? transfer_map_access_signed : transfer_map_access);
  242.     params.DataSource.data.str.data = (const byte *)map; /* bogus */
  243.     /* DataSource */
  244.     params.BitsPerSample = 8;    /* could be 16 */
  245.     params.Encode = 0;
  246.     params.Decode = 0;
  247.     params.Size = &size;
  248.     code = gs_function_Sd_init(&pfn, ¶ms, mem);
  249.     if (code < 0)
  250.     return code;
  251.     code = pdf_write_function(pdev, pfn, &id);
  252.     gs_function_free(pfn, false, mem);
  253.     if (code < 0)
  254.     return code;
  255.     sprintf(ids, "%s %ld 0 R", key, id);
  256.     return 0;
  257. }
  258. private int
  259. pdf_write_transfer(gx_device_pdf *pdev, const gx_transfer_map *map,
  260.            const char *key, char *ids)
  261. {
  262.     return pdf_write_transfer_map(pdev, map, 0, true, key, ids);
  263. }
  264.  
  265. /* ------ Halftones ------ */
  266.  
  267. /* Recognize the predefined PDF halftone functions. */
  268. #ifdef __PROTOTYPES__
  269. #define HT_FUNC(name, expr)\
  270.   private floatp name(floatp x, floatp y) { return expr; }
  271. #else
  272. #define HT_FUNC(name, expr)\
  273.   private floatp name(x, y) floatp x, y; { return expr; }
  274. #endif
  275. /* Some systems define M_2PI, M_2_PI, ... */
  276. #ifndef M_2PI
  277. #  define M_2PI (2 * M_PI)
  278. #endif
  279. HT_FUNC(ht_EllipseA, 1 - (x * x + 0.9 * y * y))
  280. HT_FUNC(ht_InvertedEllipseA, x * x + 0.9 * y * y - 1)
  281. HT_FUNC(ht_EllipseB, 1 - sqrt(x * x + 0.625 * y * y))
  282. HT_FUNC(ht_EllipseC, 1 - (0.9 * x * x + y * y))
  283. HT_FUNC(ht_InvertedEllipseC, 0.9 * x * x + y * y - 1)
  284. HT_FUNC(ht_Line, -fabs(y))
  285. HT_FUNC(ht_LineX, x)
  286. HT_FUNC(ht_LineY, y)
  287. HT_FUNC(ht_Square, -max(fabs(x), fabs(y)))
  288. HT_FUNC(ht_Cross, -min(fabs(x), fabs(y)))
  289. HT_FUNC(ht_Rhomboid, (0.9 * fabs(x) + fabs(y)) / 2)
  290. HT_FUNC(ht_DoubleDot, (sin(x * M_2PI) + sin(y * M_2PI)) / 2)
  291. HT_FUNC(ht_InvertedDoubleDot, -(sin(x * M_2PI) + sin(y * M_2PI)) / 2)
  292. HT_FUNC(ht_SimpleDot, 1 - (x * x + y * y))
  293. HT_FUNC(ht_InvertedSimpleDot, x * x + y * y - 1)
  294. HT_FUNC(ht_CosineDot, (cos(x * M_PI) + cos(y * M_PI)) / 2)
  295. HT_FUNC(ht_Double, (sin(x * M_PI) + sin(y * M_2PI)) / 2)
  296. HT_FUNC(ht_InvertedDouble, -(sin(x * M_PI) + sin(y * M_2PI)) / 2)
  297. typedef struct ht_function_s {
  298.     const char *fname;
  299.     floatp (*proc)(P2(floatp, floatp));
  300. } ht_function_t;
  301. private const ht_function_t ht_functions[] = {
  302.     {"EllipseA", ht_EllipseA},
  303.     {"InvertedEllipseA", ht_InvertedEllipseA},
  304.     {"EllipseB", ht_EllipseB},
  305.     {"EllipseC", ht_EllipseC},
  306.     {"InvertedEllipseC", ht_InvertedEllipseC},
  307.     {"Line", ht_Line},
  308.     {"LineX", ht_LineX},
  309.     {"LineY", ht_LineY},
  310.     {"Square", ht_Square},
  311.     {"Cross", ht_Cross},
  312.     {"Rhomboid", ht_Rhomboid},
  313.     {"DoubleDot", ht_DoubleDot},
  314.     {"InvertedDoubleDot", ht_InvertedDoubleDot},
  315.     {"SimpleDot", ht_SimpleDot},
  316.     {"InvertedSimpleDot", ht_InvertedSimpleDot},
  317.     {"CosineDot", ht_CosineDot},
  318.     {"Double", ht_Double},
  319.     {"InvertedDouble", ht_InvertedDouble}
  320. };
  321.  
  322. /* Write each kind of halftone. */
  323. private int
  324. pdf_write_spot_function(gx_device_pdf *pdev, const gx_ht_order *porder,
  325.             long *pid)
  326. {
  327.     /****** DOESN'T HANDLE STRIP HALFTONES ******/
  328.     int w = porder->width, h = porder->height;
  329.     uint num_bits = porder->num_bits;
  330.     gs_function_Sd_params_t params;
  331.     static const float domain_spot[4] = { -1, 1, -1, 1 };
  332.     static const float range_spot[4] = { -1, 1 };
  333.     int size[2];
  334.     gs_memory_t *mem = pdev->pdf_memory;
  335.     /*
  336.      * Even though the values are logically ushort, we must always store
  337.      * them in big-endian order, so we access them as bytes.
  338.      */
  339.     byte *values;
  340.     gs_function_t *pfn;
  341.     uint i;
  342.     int code = 0;
  343.  
  344.     params.m = 2;
  345.     params.Domain = domain_spot;
  346.     params.n = 1;
  347.     params.Range = range_spot;
  348.     params.Order = 0;        /* default */
  349.     /*
  350.      * We could use 8, 16, or 32 bits per sample to save space, but for
  351.      * simplicity, we always use 16.
  352.      */
  353.     if (num_bits > 0x10000)
  354.     return_error(gs_error_rangecheck);
  355.     params.BitsPerSample = 16;
  356.     params.Encode = 0;
  357.     /*
  358.      * The default Decode array maps the actual data values [1 .. w*h] to a
  359.      * sub-interval of the Range, but that's OK, since all that matters is
  360.      * the relative values, not the absolute values.
  361.      */
  362.     params.Decode = 0;
  363.     size[0] = w;
  364.     size[1] = h;
  365.     params.Size = size;
  366.     /* Create the (temporary) threshold array. */
  367.     values = gs_alloc_byte_array(mem, num_bits, 2, "pdf_write_spot_function");
  368.     if (values == 0)
  369.     return_error(gs_error_VMerror);
  370.     for (i = 0; i < num_bits; ++i) {
  371.     gs_int_point pt;
  372.     int value;
  373.  
  374.     if ((code = porder->procs->bit_index(porder, i, &pt)) < 0)
  375.         break;
  376.     value = pt.y * w + pt.x;
  377.     /* Always store the values in big-endian order. */
  378.     values[i * 2] = (byte)(value >> 8);
  379.     values[i * 2 + 1] = (byte)value;
  380.     }
  381.     data_source_init_bytes(¶ms.DataSource, (const byte *)values,
  382.                sizeof(*values) * num_bits);
  383.     if (code >= 0 &&
  384.     (code = gs_function_Sd_init(&pfn, ¶ms, mem)) >= 0
  385.     ) {
  386.     code = pdf_write_function(pdev, pfn, pid);
  387.     gs_function_free(pfn, false, mem);
  388.     }
  389.     gs_free_object(mem, values, "pdf_write_spot_function");
  390.     return code;
  391. }
  392. private int
  393. pdf_write_spot_halftone(gx_device_pdf *pdev, const gs_spot_halftone *psht,
  394.             const gx_ht_order *porder, long *pid)
  395. {
  396.     char trs[17 + MAX_FN_CHARS + 1];
  397.     int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
  398.                   trs);
  399.     long id, spot_id;
  400.     stream *s;
  401.     int i = countof(ht_functions);
  402.     gs_memory_t *mem = pdev->pdf_memory;
  403.  
  404.     if (code < 0)
  405.     return code;
  406.     /*
  407.      * See if we can recognize the spot function, by comparing its sampled
  408.      * values against those in the order.
  409.      */
  410.     {
  411.     gs_screen_enum senum;
  412.     gx_ht_order order;
  413.     int code;
  414.  
  415.     order = *porder;
  416.     code = gs_screen_order_alloc(&order, mem);
  417.     if (code < 0)
  418.         goto notrec;
  419.     for (i = 0; i < countof(ht_functions); ++i) {
  420.         floatp (*spot_proc)(P2(floatp, floatp)) = ht_functions[i].proc;
  421.         gs_point pt;
  422.  
  423.         gs_screen_enum_init_memory(&senum, &order, NULL, &psht->screen,
  424.                        mem);
  425.         while ((code = gs_screen_currentpoint(&senum, &pt)) == 0 &&
  426.            gs_screen_next(&senum, spot_proc(pt.x, pt.y)) >= 0)
  427.         DO_NOTHING;
  428.         if (code < 0)
  429.         continue;
  430.         /* Compare the bits and levels arrays. */
  431.         if (memcmp(order.levels, porder->levels,
  432.                order.num_levels * sizeof(*order.levels)))
  433.         continue;
  434.         if (memcmp(order.bit_data, porder->bit_data,
  435.                order.num_bits * porder->procs->bit_data_elt_size))
  436.         continue;
  437.         /* We have a match. */
  438.         break;
  439.     }
  440.     gx_ht_order_release(&order, mem, false);
  441.     }
  442.  notrec:
  443.     if (i == countof(ht_functions)) {
  444.     /* Create and write a Function for the spot function. */
  445.     pdf_write_spot_function(pdev, porder, &spot_id);
  446.     }    
  447.     *pid = id = pdf_begin_separate(pdev);
  448.     s = pdev->strm;
  449.     pprintg2(s, "<</Type/Halftone/HalftoneType 1/Frequency %g/Angle %g",
  450.          psht->screen.actual_frequency, psht->screen.actual_angle);
  451.     if (i < countof(ht_functions))
  452.     pprints1(s, "/SpotFunction/%s", ht_functions[i].fname);
  453.     else
  454.     pprintld1(s, "/SpotFunction %ld 0 R", spot_id);
  455.     pputs(s, trs);
  456.     if (psht->accurate_screens)
  457.     pputs(s, "/AccurateScreens true");
  458.     pputs(s, ">>\n");
  459.     return pdf_end_separate(pdev);
  460. }
  461. private int
  462. pdf_write_screen_halftone(gx_device_pdf *pdev, const gs_screen_halftone *psht,
  463.               const gx_ht_order *porder, long *pid)
  464. {
  465.     gs_spot_halftone spot;
  466.  
  467.     spot.screen = *psht;
  468.     spot.accurate_screens = false;
  469.     spot.transfer = 0;
  470.     spot.transfer_closure.proc = 0;
  471.     return pdf_write_spot_halftone(pdev, &spot, porder, pid);
  472. }
  473. private int
  474. pdf_write_colorscreen_halftone(gx_device_pdf *pdev,
  475.                    const gs_colorscreen_halftone *pcsht,
  476.                    const gx_device_halftone *pdht, long *pid)
  477. {
  478.     int i;
  479.     stream *s;
  480.     long ht_ids[4];
  481.  
  482.     for (i = 0; i < 4; ++i) {
  483.     int code = pdf_write_screen_halftone(pdev, &pcsht->screens.indexed[i],
  484.                          &pdht->components[i].corder,
  485.                          &ht_ids[i]);
  486.     if (code < 0)
  487.         return code;
  488.     }
  489.     *pid = pdf_begin_separate(pdev);
  490.     s = pdev->strm;
  491.     pprintld1(s, "<</Type/Halftone/HalftoneType 5/Default %ld 0 R\n",
  492.           ht_ids[3]);
  493.     pprintld2(s, "/Red %ld 0 R/Cyan %ld 0 R", ht_ids[0], ht_ids[0]);
  494.     pprintld2(s, "/Green %ld 0 R/Magenta %ld 0 R", ht_ids[1], ht_ids[1]);
  495.     pprintld2(s, "/Blue %ld 0 R/Yellow %ld 0 R", ht_ids[2], ht_ids[2]);
  496.     pprintld2(s, "/Gray %ld 0 R/Black %ld 0 R", ht_ids[3], ht_ids[3]);
  497.     return pdf_end_separate(pdev);
  498. }
  499. private int
  500. pdf_write_threshold_halftone(gx_device_pdf *pdev,
  501.                  const gs_threshold_halftone *ptht,
  502.                  const gx_ht_order *porder, long *pid)
  503. {
  504.     char trs[17 + MAX_FN_CHARS + 1];
  505.     int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
  506.                   trs);
  507.     long id = pdf_begin_separate(pdev);
  508.     stream *s = pdev->strm;
  509.     pdf_data_writer_t writer;
  510.  
  511.     if (code < 0)
  512.     return code;
  513.     *pid = id;
  514.     pprintd2(s, "<</Type/Halftone/HalftoneType 6/Width %d/Height %d",
  515.          ptht->width, ptht->height);
  516.     pputs(s, trs);
  517.     code = pdf_begin_data(pdev, &writer);
  518.     if (code < 0)
  519.     return code;
  520.     pwrite(writer.binary.strm, ptht->thresholds.data, ptht->thresholds.size);
  521.     return pdf_end_data(&writer);
  522. }
  523. private int
  524. pdf_write_threshold2_halftone(gx_device_pdf *pdev,
  525.                   const gs_threshold2_halftone *ptht,
  526.                   const gx_ht_order *porder, long *pid)
  527. {
  528.     char trs[17 + MAX_FN_CHARS + 1];
  529.     int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
  530.                   trs);
  531.     long id = pdf_begin_separate(pdev);
  532.     stream *s = pdev->strm;
  533.     pdf_data_writer_t writer;
  534.  
  535.     if (code < 0)
  536.     return code;
  537.     *pid = id;
  538.     pprintd2(s, "<</Type/Halftone/HalftoneType 16/Width %d/Height %d",
  539.          ptht->width, ptht->height);
  540.     if (ptht->width2 && ptht->height2)
  541.     pprintd2(s, "/Width2 %d/Height2 %d", ptht->width2, ptht->height2);
  542.     pputs(s, trs);
  543.     code = pdf_begin_data(pdev, &writer);
  544.     if (code < 0)
  545.     return code;
  546.     s = writer.binary.strm;
  547.     if (ptht->bytes_per_sample == 2)
  548.     pwrite(s, ptht->thresholds.data, ptht->thresholds.size);
  549.     else {
  550.     /* Expand 1-byte to 2-byte samples. */
  551.     int i;
  552.  
  553.     for (i = 0; i < ptht->thresholds.size; ++i) {
  554.         byte b = ptht->thresholds.data[i];
  555.  
  556.         pputc(s, b);
  557.         pputc(s, b);
  558.     }
  559.     }
  560.     return pdf_end_data(&writer);
  561. }
  562. private int
  563. pdf_write_multiple_halftone(gx_device_pdf *pdev,
  564.                 const gs_multiple_halftone *pmht,
  565.                 const gx_device_halftone *pdht, long *pid)
  566. {
  567.     stream *s;
  568.     int i, code;
  569.     gs_memory_t *mem = pdev->pdf_memory;
  570.     long *ids;
  571.  
  572.     ids = (long *)gs_alloc_byte_array(mem, pmht->num_comp, sizeof(long),
  573.                       "pdf_write_multiple_halftone");
  574.     if (ids == 0)
  575.     return_error(gs_error_VMerror);
  576.     for (i = 0; i < pmht->num_comp; ++i) {
  577.     const gs_halftone_component *const phtc = &pmht->components[i];
  578.     const gx_ht_order *porder =
  579.         (pdht->components == 0 ? &pdht->order :
  580.          &pdht->components[i].corder);
  581.  
  582.     switch (phtc->type) {
  583.     case ht_type_spot:
  584.         code = pdf_write_spot_halftone(pdev, &phtc->params.spot,
  585.                        porder, &ids[i]);
  586.         break;
  587.     case ht_type_threshold:
  588.         code = pdf_write_threshold_halftone(pdev, &phtc->params.threshold,
  589.                         porder, &ids[i]);
  590.         break;
  591.     case ht_type_threshold2:
  592.         code = pdf_write_threshold2_halftone(pdev,
  593.                          &phtc->params.threshold2,
  594.                          porder, &ids[i]);
  595.         break;
  596.     default:
  597.         code = gs_note_error(gs_error_rangecheck);
  598.     }
  599.     if (code < 0) {
  600.         gs_free_object(mem, ids, "pdf_write_multiple_halftone");
  601.         return code;
  602.     }
  603.     }
  604.     *pid = pdf_begin_separate(pdev);
  605.     s = pdev->strm;
  606.     pputs(s, "<</Type/Halftone/HalftoneType 5\n");
  607.     for (i = 0; i < pmht->num_comp; ++i) {
  608.     const gs_halftone_component *const phtc = &pmht->components[i];
  609.     cos_value_t value;
  610.  
  611.     code = pdf_separation_name(pdev, &value, phtc->cname);
  612.     if (code < 0)
  613.         return code;
  614.     cos_value_write(&value, pdev);
  615.     gs_free_string(mem, value.contents.chars.data,
  616.                value.contents.chars.size,
  617.                "pdf_write_multiple_halftone");
  618.     pprintld1(s, " %ld 0 R\n", ids[i]);
  619.     }
  620.     pputs(s, ">>\n");
  621.     gs_free_object(mem, ids, "pdf_write_multiple_halftone");
  622.     return pdf_end_separate(pdev);
  623. }
  624.  
  625. /*
  626.  * Update the halftone.  This is a separate procedure only for
  627.  * readability.
  628.  */
  629. private int
  630. pdf_update_halftone(gx_device_pdf *pdev, const gs_imager_state *pis,
  631.             char *hts)
  632. {
  633.     const gs_halftone *pht = pis->halftone;
  634.     const gx_device_halftone *pdht = pis->dev_ht;
  635.     int code;
  636.     long id;
  637.  
  638.     switch (pht->type) {
  639.     case ht_type_screen:
  640.     code = pdf_write_screen_halftone(pdev, &pht->params.screen,
  641.                      &pdht->order, &id);
  642.     break;
  643.     case ht_type_colorscreen:
  644.     code = pdf_write_colorscreen_halftone(pdev, &pht->params.colorscreen,
  645.                           pdht, &id);
  646.     break;
  647.     case ht_type_spot:
  648.     code = pdf_write_spot_halftone(pdev, &pht->params.spot,
  649.                        &pdht->order, &id);
  650.     break;
  651.     case ht_type_threshold:
  652.     code = pdf_write_threshold_halftone(pdev, &pht->params.threshold,
  653.                         &pdht->order, &id);
  654.     break;
  655.     case ht_type_threshold2:
  656.     code = pdf_write_threshold2_halftone(pdev, &pht->params.threshold2,
  657.                          &pdht->order, &id);
  658.     break;
  659.     case ht_type_multiple:
  660.     case ht_type_multiple_colorscreen:
  661.     code = pdf_write_multiple_halftone(pdev, &pht->params.multiple,
  662.                        pdht, &id);
  663.     break;
  664.     default:
  665.     return_error(gs_error_rangecheck);
  666.     }
  667.     if (code < 0)
  668.     return code;
  669.     sprintf(hts, "/HT %ld 0 R", id);
  670.     pdev->halftone_id = pis->dev_ht->id;
  671.     return code;
  672. }
  673.  
  674. /* ------ Graphics state updating ------ */
  675.  
  676. /* Open an ExtGState. */
  677. private int
  678. pdf_open_gstate(gx_device_pdf *pdev, pdf_resource_t **ppres)
  679. {
  680.     if (*ppres)
  681.     return 0;
  682.     return pdf_begin_resource(pdev, resourceExtGState, gs_no_id, ppres);
  683. }
  684.  
  685. /* Finish writing an ExtGState. */
  686. private int
  687. pdf_end_gstate(gx_device_pdf *pdev, pdf_resource_t *pres)
  688. {
  689.     if (pres) {
  690.     int code;
  691.  
  692.     pputs(pdev->strm, ">>\n");
  693.     code = pdf_end_resource(pdev);
  694.     pres->object->written = true; /* don't write at end of page */
  695.     if (code < 0)
  696.         return code;
  697.     code = pdf_open_page(pdev, PDF_IN_STREAM);
  698.     if (code < 0)
  699.         return code;
  700.     pprintld1(pdev->strm, "/R%ld gs\n", pdf_resource_id(pres));
  701.     }
  702.     return 0;
  703. }
  704.  
  705. /*
  706.  * Update the transfer functions(s).  This is a separate procedure only
  707.  * for readability.
  708.  */
  709. private int
  710. pdf_update_transfer(gx_device_pdf *pdev, const gs_imager_state *pis,
  711.             char *trs)
  712. {
  713.     int i;
  714.     bool multiple = false, update = false;
  715.     gs_id transfer_ids[4];
  716.     int code = 0;
  717.  
  718.     for (i = 0; i < 4; ++i) {
  719.     transfer_ids[i] = pis->set_transfer.indexed[i]->id;
  720.     if (pdev->transfer_ids[i] != transfer_ids[i])
  721.         update = true;
  722.     if (transfer_ids[i] != transfer_ids[0])
  723.         multiple = true;
  724.     }
  725.     if (update) {
  726.     if (!multiple) {
  727.         code = pdf_write_transfer(pdev, pis->set_transfer.indexed[0],
  728.                       "/TR", trs);
  729.         if (code < 0)
  730.         return code;
  731.     } else {
  732.         strcpy(trs, "/TR[");
  733.         for (i = 0; i < 4; ++i) {
  734.         code = pdf_write_transfer_map(pdev,
  735.                           pis->set_transfer.indexed[i],
  736.                           0, false, "", trs + strlen(trs));
  737.         if (code < 0)
  738.             return code;
  739.         }
  740.         strcat(trs, "]");
  741.     }
  742.     memcpy(pdev->transfer_ids, transfer_ids, sizeof(pdev->transfer_ids));
  743.     }
  744.     return code;
  745. }
  746.  
  747. /*
  748.  * Update the current alpha if necessary.  Note that because Ghostscript
  749.  * stores separate opacity and shape alpha, a rangecheck will occur if
  750.  * both are different from the current setting.
  751.  */
  752. private int
  753. pdf_update_alpha(gx_device_pdf *pdev, const gs_imager_state *pis,
  754.          const char *ca_format, pdf_resource_t **ppres)
  755. {
  756.     bool ais;
  757.     floatp alpha;
  758.     int code;
  759.  
  760.     if (pdev->state.opacity.alpha != pis->opacity.alpha) {
  761.     if (pdev->state.shape.alpha != pis->shape.alpha)
  762.         return_error(gs_error_rangecheck);
  763.     ais = false;
  764.     alpha = pdev->state.opacity.alpha = pis->opacity.alpha;
  765.     } else if (pdev->state.shape.alpha != pis->shape.alpha) {
  766.     ais = true;
  767.     alpha = pdev->state.shape.alpha = pis->shape.alpha;
  768.     } else
  769.     return 0;
  770.     code = pdf_open_gstate(pdev, ppres);
  771.     if (code < 0)
  772.     return code;
  773.     pprintb1(pdev->strm, "/AIS %s", ais);
  774.     pprintg1(pdev->strm, ca_format, alpha);
  775.     return 0;
  776. }
  777.  
  778. /*
  779.  * Update the graphics subset common to all high-level drawing operations.
  780.  */
  781. private int
  782. pdf_prepare_drawing(gx_device_pdf *pdev, const gs_imager_state *pis,
  783.             const char *ca_format, pdf_resource_t **ppres)
  784. {
  785.     int code;
  786.  
  787.     if (pdev->CompatibilityLevel >= 1.4) {
  788.     if (pdev->state.blend_mode != pis->blend_mode) {
  789.         static const char *const bm_names[] = { GS_BLEND_MODE_NAMES };
  790.  
  791.         code = pdf_open_gstate(pdev, ppres);
  792.         if (code < 0)
  793.         return code;
  794.         pprints1(pdev->strm, "/BM/%s", bm_names[pis->blend_mode]);
  795.         pdev->state.blend_mode = pis->blend_mode;
  796.     }
  797.     code = pdf_update_alpha(pdev, pis, ca_format, ppres);
  798.     if (code < 0)
  799.         return code;
  800.     } else {
  801.     /*
  802.      * If the graphics state calls for any transparency functions,
  803.      * we can't represent them, so return a rangecheck.
  804.      */
  805.     if (pis->opacity.alpha != 1 || pis->opacity.mask != 0 ||
  806.         pis->shape.alpha != 1 || pis->shape.mask != 0 ||
  807.         pis->transparency_stack != 0
  808.         )
  809.         return_error(gs_error_rangecheck);
  810.     }
  811.     return 0;
  812. }
  813.  
  814. /* Update the graphics state subset common to fill and stroke. */
  815. private int
  816. pdf_prepare_vector(gx_device_pdf *pdev, const gs_imager_state *pis,
  817.            const char *ca_format, pdf_resource_t **ppres)
  818. {
  819.     /*
  820.      * Update halftone, transfer function, black generation, undercolor
  821.      * removal, halftone phase, overprint mode, smoothness, blend mode, text
  822.      * knockout.
  823.      */
  824.     int code = pdf_prepare_drawing(pdev, pis, ca_format, ppres);
  825.  
  826.     if (code < 0)
  827.     return code;
  828.     if (pdev->CompatibilityLevel >= 1.2) {
  829.     gs_int_point phase, dev_phase;
  830.     char hts[5 + MAX_FN_CHARS + 1],
  831.         trs[5 + MAX_FN_CHARS * 4 + 6 + 1],
  832.         bgs[5 + MAX_FN_CHARS + 1],
  833.         ucrs[6 + MAX_FN_CHARS + 1];
  834.  
  835.     hts[0] = trs[0] = bgs[0] = ucrs[0] = 0;
  836.     if (pdev->params.PreserveHalftoneInfo &&
  837.         pdev->halftone_id != pis->dev_ht->id
  838.         ) {
  839.         code = pdf_update_halftone(pdev, pis, hts);
  840.         if (code < 0)
  841.         return code;
  842.     }
  843.     if (pdev->params.TransferFunctionInfo == tfi_Preserve) {
  844.         code = pdf_update_transfer(pdev, pis, trs);
  845.         if (code < 0)
  846.         return code;
  847.     }
  848.     if (pdev->params.UCRandBGInfo == ucrbg_Preserve) {
  849.         if (pdev->black_generation_id != pis->black_generation->id) {
  850.         code = pdf_write_transfer_map(pdev, pis->black_generation,
  851.                           0, false, "/BG", bgs);
  852.         if (code < 0)
  853.             return code;
  854.         pdev->black_generation_id = pis->black_generation->id;
  855.         }
  856.         if (pdev->undercolor_removal_id != pis->undercolor_removal->id) {
  857.         code = pdf_write_transfer_map(pdev, pis->undercolor_removal,
  858.                           -1, false, "/UCR", ucrs);
  859.         if (code < 0)
  860.             return code;
  861.         pdev->undercolor_removal_id = pis->undercolor_removal->id;
  862.         }
  863.     }
  864.     if (hts[0] || trs[0] || bgs[0] || ucrs[0]) {
  865.         code = pdf_open_gstate(pdev, ppres);
  866.         if (code < 0)
  867.         return code;
  868.         pputs(pdev->strm, hts);
  869.         pputs(pdev->strm, trs);
  870.         pputs(pdev->strm, bgs);
  871.         pputs(pdev->strm, ucrs);
  872.     }
  873.     gs_currenthalftonephase((const gs_state *)pis, &phase);
  874.     gs_currenthalftonephase((const gs_state *)&pdev->state, &dev_phase);
  875.     if (dev_phase.x != phase.x || dev_phase.y != phase.y) {
  876.         code = pdf_open_gstate(pdev, ppres);
  877.         if (code < 0)
  878.         return code;
  879.         pprintd2(pdev->strm, "/HTP[%d %d]", phase.x, phase.y);
  880.         gx_imager_setscreenphase(&pdev->state, phase.x, phase.y,
  881.                      gs_color_select_all);
  882.     }
  883.     }
  884.     if (pdev->CompatibilityLevel >= 1.3) {
  885.     if (pdev->overprint_mode != pdev->params.OPM) {
  886.         code = pdf_open_gstate(pdev, ppres);
  887.         if (code < 0)
  888.         return code;
  889.         pprintd1(pdev->strm, "/OPM %d", pdev->params.OPM);
  890.         pdev->overprint_mode = pdev->params.OPM;
  891.     }
  892.     if (pdev->state.smoothness != pis->smoothness) {
  893.         code = pdf_open_gstate(pdev, ppres);
  894.         if (code < 0)
  895.         return code;
  896.         pprintg1(pdev->strm, "/SM %g", pis->smoothness);
  897.         pdev->state.smoothness = pis->smoothness;
  898.     }
  899.     if (pdev->CompatibilityLevel >= 1.4) {
  900.         if (pdev->state.text_knockout != pis->text_knockout) {
  901.         code = pdf_open_gstate(pdev, ppres);
  902.         if (code < 0)
  903.             return code;
  904.         pprintb1(pdev->strm, "/TK %s", pis->text_knockout);
  905.         pdev->state.text_knockout = pis->text_knockout;
  906.         }
  907.     }
  908.     }
  909.     return code;
  910. }
  911.  
  912. /* Update the graphics state for filling. */
  913. int
  914. pdf_prepare_fill(gx_device_pdf *pdev, const gs_imager_state *pis)
  915. {
  916.     pdf_resource_t *pres = 0;
  917.     int code = pdf_prepare_vector(pdev, pis, "/ca %g", &pres);
  918.  
  919.     if (code < 0)
  920.     return code;
  921.     /* Update overprint. */
  922.     if (pdev->CompatibilityLevel >= 1.2) {
  923.     if (pdev->params.PreserveOverprintSettings &&
  924.         pdev->fill_overprint != pis->overprint
  925.         ) {
  926.         code = pdf_open_gstate(pdev, &pres);
  927.         if (code < 0)
  928.         return code;
  929.         /* PDF 1.2 only has a single overprint setting. */
  930.         if (pdev->CompatibilityLevel < 1.3) {
  931.         pprintb1(pdev->strm, "/OP %s", pis->overprint);
  932.         pdev->stroke_overprint = pis->overprint;
  933.         } else {
  934.         pprintb1(pdev->strm, "/op %s", pis->overprint);
  935.         }
  936.         pdev->fill_overprint = pis->overprint;
  937.     }
  938.     }
  939.     return pdf_end_gstate(pdev, pres);
  940. }
  941.  
  942. /* Update the graphics state for stroking. */
  943. int
  944. pdf_prepare_stroke(gx_device_pdf *pdev, const gs_imager_state *pis)
  945. {
  946.     pdf_resource_t *pres = 0;
  947.     int code = pdf_prepare_vector(pdev, pis, "/CA %g", &pres);
  948.  
  949.     if (code < 0)
  950.     return code;
  951.     /* Update overprint, stroke adjustment. */
  952.     if (pdev->CompatibilityLevel >= 1.2) {
  953.     if (pdev->params.PreserveOverprintSettings &&
  954.         pdev->stroke_overprint != pis->overprint
  955.         ) {
  956.         code = pdf_open_gstate(pdev, &pres);
  957.         if (code < 0)
  958.         return code;
  959.         pprintb1(pdev->strm, "/OP %s", pis->overprint);
  960.         pdev->stroke_overprint = pis->overprint;
  961.         /* PDF 1.2 only has a single overprint setting. */
  962.         if (pdev->CompatibilityLevel < 1.3)
  963.         pdev->fill_overprint = pis->overprint;
  964.     }
  965.     if (pdev->state.stroke_adjust != pis->stroke_adjust) {
  966.         code = pdf_open_gstate(pdev, &pres);
  967.         if (code < 0)
  968.         return code;
  969.         pprintb1(pdev->strm, "/SA %s", pis->stroke_adjust);
  970.         pdev->state.stroke_adjust = pis->stroke_adjust;
  971.     }
  972.     }
  973.     return pdf_end_gstate(pdev, pres);
  974. }
  975.  
  976. /* Update the graphics state for an image other than an ImageType 1 mask. */
  977. int
  978. pdf_prepare_image(gx_device_pdf *pdev, const gs_imager_state *pis)
  979. {
  980.     pdf_resource_t *pres = 0;
  981.     int code = pdf_prepare_drawing(pdev, pis, "/ca %g", &pres);
  982.  
  983.     if (code < 0)
  984.     return code;
  985.     return pdf_end_gstate(pdev, pres);
  986. }
  987.  
  988. /* Update the graphics state for an ImageType 1 mask. */
  989. int
  990. pdf_prepare_imagemask(gx_device_pdf *pdev, const gs_imager_state *pis,
  991.               const gx_drawing_color *pdcolor)
  992. {
  993.     int code = pdf_prepare_image(pdev, pis);
  994.  
  995.     if (code < 0)
  996.     return code;
  997.     return pdf_set_drawing_color(pdev, pdcolor, &pdev->fill_color,
  998.                  &psdf_set_fill_color_commands);
  999. }
  1000.